import axios from 'axios';
import { Logger } from './logger';
import * as vscode from 'vscode';

export interface RemoteConfig {
  apiKey: string;
  apiEndpoint: string;
  langChainEndpoint: string;
  maxDiffLength: number;
  timeout: number;
}

//配置默认值
const DEFAULT_CONFIG: RemoteConfig = {
  apiKey: 'app-8z24OneOsmSno1gFTwGY2Pjg',
  apiEndpoint: 'https://dify.cyouai.com/v1/chat-messages',
  langChainEndpoint: 'https://langchain.cyouai.com/v1/aggregate-commit',
  maxDiffLength: 100000,
  timeout: 180000
};

/** 远程配置接口地址 */
const CONFIG_URL = 'https://test-jobs.cyouops.com/config_center/api/v1/configs/demo/application';

/** 远程配置请求超时时间（毫秒，10秒） */
const CONFIG_FETCH_TIMEOUT = 10000;

export function maskApiKey(apiKey: string): string {
  if (!apiKey || apiKey.length <= 6) return '***';
  return apiKey.slice(0, 3) + '***' + apiKey.slice(-3);
}

export class ConfigService {
  private static config: RemoteConfig | null = null;
  private static context: vscode.ExtensionContext;

  public static initialize(context: vscode.ExtensionContext) {
    this.context = context;
  }

  public static async refreshConfig(): Promise<RemoteConfig> {
    try {
      const config = await this.fetchRemoteConfig();
      this.config = config;
      await this.context.globalState.update('remoteConfig', config);
      return config;
    } catch (e) {
      const logger = Logger.getInstance();
      logger.error('刷新远程配置失败: ' + (e instanceof Error ? e.message : e));
      vscode.window.showErrorMessage('刷新远程配置失败，继续使用本地配置');
      if (this.config) return this.config;
      const localConfig = this.context?.globalState.get<RemoteConfig>('remoteConfig');
      if (localConfig) return localConfig;
      vscode.window.showWarningMessage("无法刷新远程配置且本地无可用配置，请检查网络连接或VPN设置。已使用默认配置项")
      return DEFAULT_CONFIG;
    }
  }

  public static async getConfig(): Promise<RemoteConfig> {
    if (this.config) return this.config;
    const localConfig = this.context?.globalState.get<RemoteConfig>('remoteConfig');
    if (localConfig) {
      this.config = localConfig;
    }
    try {
      const config = await this.fetchRemoteConfig();
      this.config = config;
      await this.context.globalState.update('remoteConfig', config);
      return config;
    } catch (e) {
      const logger = Logger.getInstance();
      logger.error('拉取远程配置失败: ' + (e instanceof Error ? e.message : e));
      if (this.config) {
        vscode.window.showWarningMessage('拉取远程配置失败，已使用本地缓存配置');
        return this.config;
      }
      vscode.window.showWarningMessage("无法获取远程配置且本地无可用配置，请检查网络连接或VPN设置。")
      return DEFAULT_CONFIG;
    }
  }

  private static async fetchRemoteConfig(): Promise<RemoteConfig> {
    const logger = Logger.getInstance();
    try {
      logger.info('开始拉取远程配置: ' + CONFIG_URL);
      const res = await axios.get(CONFIG_URL, { timeout: CONFIG_FETCH_TIMEOUT });
      logger.debug('远程返回原始内容: ' + JSON.stringify(res.data));
      // 提取configurations中的字段
      const configObj: any = res.data;
      const configurations = configObj.data?.configurations || {};
      const rest = configurations;
      // 字段值强制转换为数字类型
      const maxDiffLength = Number(rest.maxDiffLength);
      const timeout = Number(rest.timeout);
      if (isNaN(maxDiffLength) || isNaN(timeout)) {
        logger.error('maxDiffLength 或 timeout 不是有效数字');
        logger.error(`maxDiffLength 原始值: ${rest.maxDiffLength}, timeout 原始值: ${rest.timeout}`);
        throw new Error('maxDiffLength 或 timeout 不是有效数字');
      }
      const data: RemoteConfig = {
        apiKey: rest.apiKey,
        apiEndpoint: rest.apiEndpoint,
        langChainEndpoint: rest.langChainEndpoint || 'https://langchain.cyouai.com/v1/aggregate-commit',
        maxDiffLength,
        timeout,
      };
      logger.info(
        `远程配置拉取成功: apiKey=${maskApiKey(data.apiKey)}, apiEndpoint=${data.apiEndpoint}, langChainEndpoint=${data.langChainEndpoint}, maxDiffLength=${data.maxDiffLength}, timeout=${data.timeout}`
      );
      logger.debug('typeof data.maxDiffLength: ' + typeof data.maxDiffLength + ' ' + data.maxDiffLength);
      logger.debug('typeof data.timeout: ' + typeof data.timeout + ' ' + data.timeout);
      if (!data.apiKey || !data.apiEndpoint || !data.langChainEndpoint || !data.maxDiffLength || !data.timeout) {
        logger.error('远程配置缺少必要字段');
        throw new Error('远程配置缺少必要字段');
      }
      return data;
    } catch (e) {
      logger.error('无法获取远程配置: ' + (e instanceof Error ? e.message : e));
      throw new Error('无法获取远程配置: ' + (e instanceof Error ? e.message : e));
    }
  }
}


